package com.mzz.creational.singleton;

/**
 * (2)
 *
 * @author xushijian
 * @describe 这种方式具备很好的 lazy loading，能够在多线程中很好的工作，但是，效率很低，99% 情况下不需要同步。
 * <p>
 * 优点：第一次调用才初始化，避免内存浪费。
 * <p>
 * 缺点：必须加锁 synchronized 才能保证单例，但加锁会影响效率。
 * <p>
 * getInstance() 的性能对应用程序不是很关键（该方法使用不太频繁）
 */
public class SingletonSynchronized2 {

    /**
     * 持有私有静态实例，防止被引用，此处赋值为null，目的是实现延迟加载
     **/
    private static SingletonSynchronized2 instance = null;

    /**
     * 私有静态方法，防止被实例化
     */
    private SingletonSynchronized2() {

    }

    //使用该类的时候被初始化  @@@ 在性能上会有所下降，因为每次调用getInstance()，都要对对象上锁(**)
    //静态方法加载实例
    public static synchronized SingletonSynchronized2 getInstance() {
        if (instance == null) {
            instance = new SingletonSynchronized2();
        }
        return instance;
    }

    //当JVM从内存中反序列化地“组装”对象时，就会自动调用这个readResolve()方法来返回我们制定好的对象。

    /**
     * 如果该对象被用于序列化，可以保证对象在序列化前后保持一致
     **/
    private Object readResolve() {
        return instance;
    }

    /**
     * 虽然对 Singleton.java 中的 getInstance() 方法加上了synchronized关键字，但是synchronized关键字锁住的是这个对象，这样的用法，
     * 在性能上会有所下降，因为每次调用getInstance()，都要对对象上锁。
     * 事实上，只有在第一次创建对象的时候需要加锁，之后就不需要了，所以，这个地方需要改进。
     *
     * 改动后的代码，请点击查看 Singleton3.java
     *
     *
     */
}
